import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, Like, In } from 'typeorm';
import { Article } from '../../entities/article.entity';
import { Tag } from '../../entities/tag.entity';
import { CreateArticleDto, UpdateArticleDto, ArticleResponseDto } from '../../dto/article.dto';
import { UserService } from '../user/user.service';
import { TagService } from '../tag/tag.service';
import { UserResponseDto } from 'src/dto/user.dto';


@Injectable()
export class ArticleService {
  
  constructor(
    @InjectRepository(Article)
    private readonly articlesRepository: Repository<Article>,
    private userService: UserService,
    private tagService: TagService,
  ) {}

  async create(createArticleDto: CreateArticleDto, userId: number): Promise<ArticleResponseDto> {
    // 创建文章对象
    const article = this.articlesRepository.create({
      ...createArticleDto,
      authorId: userId,
      tags: [] // 初始化为空数组
    });

    // 处理标签关联
    if (createArticleDto.tagIds && createArticleDto.tagIds.length > 0) {
      // 查找所有关联的标签
      const foundTags = await this.tagService.findByIds(createArticleDto.tagIds);
      if (foundTags.length > 0) {
        article.tags = foundTags;
      }
    }

    // 保存文章（会自动建立文章和标签的关联）
    await this.articlesRepository.save(article);
    
    // 更新标签使用次数
    await this.tagService.updateUsageCount();
    
    // 重新加载文章以获取完整的标签信息
    const savedArticle = await this.articlesRepository.findOne({
      where: { id: article.id },
      relations: ['tags']
    });
    
    if (!savedArticle) {
      throw new HttpException('文章创建成功但无法读取', HttpStatus.INTERNAL_SERVER_ERROR);
    }
    
    // 获取作者信息
    const userMap = await this.userService.findOne(userId);


    return new ArticleResponseDto(savedArticle, userMap);
  }

  async findAll(params: {
    categoryId?: number;
    search?: string;
    page?: number | string;
    limit?: number | string;
    isActive?: number; // 添加isActive参数，便于管理员查看所有状态的文章
  } = {}): Promise<{ articles: ArticleResponseDto[]; total: number }> {
    // 确保page和limit是有效数字
    const safePage = parseInt(params.page as string) || 1;
    const safeLimit = parseInt(params.limit as string) || 10;
    const skip = Math.max(0, (safePage - 1) * safeLimit);

    const query = this.articlesRepository.createQueryBuilder('article')
      .leftJoinAndSelect('article.tags', 'tags');

    // 默认只返回审核成功的文章，除非明确指定了isActive参数
    if (params.isActive === undefined) {
      query.andWhere('article.isActive = :isActive', { isActive: Article.STATUS_APPROVED });
    } else if (params.isActive !== null) {
      query.andWhere('article.isActive = :isActive', { isActive: params.isActive });
    }

    // 根据分类ID筛选文章
    if (params.categoryId !== undefined && params.categoryId !== null && !isNaN(Number(params.categoryId))) {
      const categoryId = Number(params.categoryId); // 明确转换为数字类型
      query.andWhere('article.categoryId = :categoryId', { categoryId });
      // console.log('====categoryId:', categoryId);
    }
    
    if (params.search) {
      // console.log('====search:', params.search);
      query.andWhere('(article.title LIKE :search OR article.content LIKE :search)', {
        search: `%${params.search}%`,
      });
    }

    const [articles, total] = await query
      .orderBy('article.createdAt', 'DESC')
      .skip(skip)
      .take(safeLimit)
      .getManyAndCount();
    console.log('====articles:', articles);
    // console.log('====total:', total);
    //获取到作者信息
  
    return {
      articles: await Promise.all(
        articles.map(async article => {
          const userMap = await this.userService.findOne(article.authorId);
          return new ArticleResponseDto(article, userMap);
        }),
      ),
      total,
    };
  }

  async findOne(id: number, userId?: number, isAdmin: boolean = false): Promise<ArticleResponseDto> {
    // 构建基本查询
    const query = this.articlesRepository.createQueryBuilder('article')
      .leftJoinAndSelect('article.tags', 'tags')
      .where('article.id = :id', { id });

    // 根据权限设置不同的查询条件
    if (isAdmin) {
      // 管理员可以查看所有文章，无权限限制
    } else if (userId) {
      // 已登录用户：可以查看自己的所有文章 或 审核通过的文章
      query.andWhere('(article.authorId = :userId OR article.isActive = :approved)', {
        userId,
        approved: Article.STATUS_APPROVED
      });
    } else {
      // 未登录用户：只能查看审核通过的文章
      query.andWhere('article.isActive = :approved', { approved: Article.STATUS_APPROVED });
    }
    
    const article = await query.getOne();
    console.log('====article:', article);
    if (!article) {
      throw new HttpException('文章不存在或无权访问', HttpStatus.NOT_FOUND);
    }

    // 增加浏览量
    article.viewCount += 1;
    await this.articlesRepository.save(article);
    // 获取作者信息
    const userMap = await this.userService.findOne(article.authorId);
    return new ArticleResponseDto(article, userMap);
  }

  async findAllAdmin(
    page: number = 1,
    pageSize: number = 10,
    keyword?: string,
    isActive?: number,
  ): Promise<{ data: ArticleResponseDto[], total: number, page: number, pageSize: number }> {
    // 构建查询条件
    const where: any = {};

    // 关键词搜索（标题或内容）
    if (keyword && keyword.trim()) {
      where.title = Like(`%${keyword.trim()}%`);
    }

    // 审核状态过滤（-1表示不过滤）
    if (isActive !== undefined && isActive !== -1) {
      where.isActive = isActive;
    }

    // 计算分页
    const skip = (page - 1) * pageSize;

    // 获取总数
    const total = await this.articlesRepository.count({ where });

    // 获取分页数据
    const articles = await this.articlesRepository.find({
      where,
      relations: ['tags'],
      order: { createdAt: 'DESC' },
      skip,
      take: pageSize,
    });

    // 转换为DTO
    const items = await Promise.all(
      articles.map(async article => {
        const user = await this.userService.findOne(article.authorId);
        return new ArticleResponseDto(article, user);
      }),
    );

    return { data: items, total, page, pageSize };
  }

  // 转换文章为响应DTO
  private toArticleResponseDto(article: Article, user?: any): ArticleResponseDto {
    return new ArticleResponseDto(article, user);
  }

  async update(id: number, updateArticleDto: UpdateArticleDto, userId: number): Promise<ArticleResponseDto> {
    const article = await this.articlesRepository.findOne({
      where: { id },
      relations: ['tags']
    });
    
    if (!article) {
      throw new HttpException('文章不存在', HttpStatus.NOT_FOUND);
    }

    // 检查权限
    if (article.authorId !== userId) {
      throw new HttpException('无权修改此文章', HttpStatus.FORBIDDEN);
    }

    // 处理标签更新
    if (updateArticleDto.tagIds !== undefined) {
      const tagIds = updateArticleDto.tagIds;
      if (tagIds && tagIds.length > 0) {
        const foundTags = await this.tagService.findByIds(tagIds);
        article.tags = foundTags;
      } else {
        article.tags = [];
      }
    }

    // 移除tagIds，避免直接更新
    const { tagIds, ...updateData } = updateArticleDto;
    
    // 更新文章数据
    await this.articlesRepository.save({ ...article, ...updateData });
    
    // 更新标签使用次数
    await this.tagService.updateUsageCount();
    
    const updatedArticle = await this.articlesRepository.findOne({
      where: { id },
      relations: ['tags']
    });
    
    // 获取作者信息
    if (!updatedArticle) {
      throw new HttpException('文章更新后未找到', HttpStatus.NOT_FOUND);
    }
    const userMap = await this.userService.findOne(updatedArticle.authorId);

    
    return new ArticleResponseDto(updatedArticle, userMap);
  }

  async updateAdmin(id: number, updateArticleDto: UpdateArticleDto): Promise<ArticleResponseDto> {
    const article = await this.articlesRepository.findOne({
      where: { id },
      relations: ['tags']
    });
    
    if (!article) {
      throw new HttpException('文章不存在', HttpStatus.NOT_FOUND);
    }

    // 管理员更新不需要检查作者权限

    // 处理标签更新
    if (updateArticleDto.tagIds !== undefined) {
      const tagIds = updateArticleDto.tagIds;
      if (tagIds && tagIds.length > 0) {
        const foundTags = await this.tagService.findByIds(tagIds);
        article.tags = foundTags;
      } else {
        article.tags = [];
      }
    }

    // 移除tagIds，避免直接更新
    const { tagIds, ...updateData } = updateArticleDto;
    
    // 更新文章数据
    await this.articlesRepository.save({ ...article, ...updateData });
    
    // 更新标签使用次数
    await this.tagService.updateUsageCount();
    
    const updatedArticle = await this.articlesRepository.findOne({
      where: { id },
      relations: ['tags']
    });
    
    // 获取作者信息
    if (!updatedArticle) {
      throw new HttpException('文章更新后未找到', HttpStatus.NOT_FOUND);
    }
    const userMap = await this.userService.findOne(updatedArticle.authorId);
    return new ArticleResponseDto(updatedArticle, userMap);
  }

  async remove(id: number, userId: number): Promise<void> {
    const article = await this.articlesRepository.findOne({
      where: { id },
      relations: ['tags']
    });
    
    if (!article) {
      throw new HttpException('文章不存在', HttpStatus.NOT_FOUND);
    }

    if (article.authorId !== userId) {
      throw new HttpException('无权删除此文章', HttpStatus.FORBIDDEN);
    }

    // 先解除与标签的关联
    article.tags = [];
    await this.articlesRepository.save(article);
    
    // 然后删除文章
    await this.articlesRepository.delete(id);
    
    // 更新标签使用次数
    await this.tagService.updateUsageCount();

  }

  async likeArticle(id: number): Promise<{ likeCount: number }> {
    const article = await this.articlesRepository.findOne({
      where: { id },
      relations: ['tags']
    });
    
    if (!article) {
      throw new HttpException('文章不存在', HttpStatus.NOT_FOUND);
    }

    article.likeCount = (article.likeCount || 0) + 1;
    await this.articlesRepository.save(article);

    // 更新标签使用次数
    await this.tagService.updateUsageCount();

    return { likeCount: article.likeCount };
  }

  async updateArticleStatus(id: number, userId: number, status: { isActive: number }): Promise<ArticleResponseDto> {
    // 查找文章
    const article = await this.articlesRepository.findOne({
      where: { id },
      relations: ['tags']
    });
    
    if (!article) {
      throw new HttpException('文章不存在', HttpStatus.NOT_FOUND);
    }
    
    // 检查是否是文章作者
    if (article.authorId !== userId) {
      throw new HttpException('没有权限更新此文章', HttpStatus.FORBIDDEN);
    }
    
    // 更新状态
    article.isActive = status.isActive;
    await this.articlesRepository.save(article);
    
    // 获取作者信息
    const user = await this.userService.findOne(userId);
    
    return new ArticleResponseDto(article, user);
  }

  async updateStatus(id: number, isActive: number): Promise<ArticleResponseDto> {
    // 管理员专用方法，权限检查由装饰器保证
    const article = await this.articlesRepository.findOne({
      where: { id },
      relations: ['tags']
    });
    
    if (!article) {
      throw new HttpException('文章不存在', HttpStatus.NOT_FOUND);
    }
    
    article.isActive = isActive;
    await this.articlesRepository.save(article);
    
    const user = await this.userService.findOne(article.authorId);
    return this.toArticleResponseDto(article, user);
  }

  async getUserArticles(userId: number): Promise<ArticleResponseDto[]> {
    // 查询当前用户的所有文章，包含标签信息
    const articles = await this.articlesRepository.find({
      where: { authorId: userId },
      relations: ['tags'],
      order: { createdAt: 'DESC' } // 按创建时间降序排序
    });
    
    // 获取作者信息（可以复用已有方法）
    const user = await this.userService.findOne(userId);
    
    // 转换为响应DTO
    return articles.map(article => new ArticleResponseDto(article, user));
  }

  async getPopularArticles(limit: number = 10): Promise<ArticleResponseDto[]> {
    // console.log('====limit:', limit);

    const articles = await this.articlesRepository.find({
      where: { isActive: Article.STATUS_APPROVED }, // 只返回审核成功的文章
      relations: ['tags'],
      order: { likeCount: 'DESC' },
      take: limit
    });

    // console.log('====articles:', articles);
    return await Promise.all(
      articles.map(async article => {
        const userMap = await this.userService.findOne(article.authorId);
        return new ArticleResponseDto(article, userMap);
      })
    );
  }

}